/*
 * XmlReader.java
 *
 * Created on 18 de Mar�o de 2003, 20:22
 */
package saci.reptil.reader;

import oracle.xml.parser.v2.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.StringReader;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import org.xml.sax.InputSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;
import java.awt.Component;
import java.awt.Font;
import java.awt.Color;
import java.awt.FontFormatException;
import java.awt.LayoutManager;
import java.net.URL;
import javax.swing.ImageIcon;
import java.awt.Dimension;
import java.lang.reflect.Constructor;
import javax.swing.border.Border;
import java.util.Vector;

import saci.reptil.DbLabel;
import saci.reptil.DetailBand;
import saci.reptil.FooterBand;
import saci.reptil.Group;
import saci.reptil.GroupFooterBand;
import saci.reptil.GroupHeaderBand;
import saci.reptil.HeaderBand;
import saci.reptil.InnerPanel;
import saci.reptil.Label;
import saci.reptil.ReportManager;
import saci.reptil.ReportPanel;
import saci.reptil.SummaryBand;
import saci.reptil.TitleBand;
import saci.reptil.event.BandListener;

/**
 * Importa um relat�rio de um arquivo XML.
 * <p>
 * <b>Utiliza a biblioteca Xerces</b>
 * <p>
 * BufferedReader in = new BufferedReader(new FileReader("meuRelatorio.xml"));<br>
 * String s, xml="";<br>
 * <br>
 * <i>//passa o conteudo do arquivo para string</i><br>
 * while((s = in.readLine()) != null) {<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;xml += s;<br>
 * }<br>
 * <br>
 * <i>// cria uma nova inst�ncia da classe</i><br>
 * XmlReader xmlReader = new XmlReader(xml);<br>
 * <br>
 * <i>// cria o ReportManager baseado no xml</i><br>
 * ReportManager rp = new ReportManager(xmlReader);<br>
 * rp.prepare(); <i>// prepara o relat�rio</i><br>
 * in.close();<br>
 * <br>
 * rp.show("Report");<i>// mostra o relat�rio</i>
 * <p>
 * <b>Arquivo XML</b><br>
 * <ul>
 *  <li><b>saci</b></li>
 *  <ul>
 *   <li><b>Connection</b> dados da conex�o com o banco de dados</li>
 *   <ul>
 *    <li>url</li>
 *    <li>driver</li>
 *    <li>user</li>
 *    <li>password</li>
 *   </ul>
 *  </ul>
 *  <ul>
 *   <li><b>report</b> data="sql:" <i>Instru��o SQL</i></li>
 *   <ul>
 *    <li>title</li>
 *    <li>header</li>
 *    <li>group</li>
 *    <ul>
 *     <li>header</li>
 *     <li>footer</li>
 *    </ul>
 *    <li>detail</li>
 *    <li>footer</li>
 *    <li>summary</li>
 *    <li>componentsInReport</li>
 *    <ul>
 *     <li>logodaempresa class="" <i>nome da classe que desenhe o logo da empresa</i> x="10" y="50"</li>
 *    </ul>
 *   </ul>
 *  </ul>
 * </ul>
 * <p>
 * <b>* todos as bandas do relat�rio precisam ter altura <i>(height)</i> definidas</b>
 * <p>
 * <b>parametros do <i>Report</i></b><br>
 * * <b>data</b> A fonte de dados do relat�rio "SQL:" + instru��o SQL<br>
 * * <b>paper</b> O papel <i>(LETTER, A4, A3, LEGAL)</i> padr�o <i>A4</i><br>
 * * <b>orientation</b> A orienta��o do papel <i>(LANDSCAPE ou PORTRAIT)</i> padr�o <i>PORTRAIT</i><br>
 * * <b>width</b> A largura do papel em px<br>
 * * <b>height</b> A altura do papel em px<br>
 * * <b>marginX</b> A posi��o X da margem<br>
 * * <b>marginY</b> A posi��o Y da margem<br>
 * * <b>marginWidth</b> A largura vis�vel do papel<br>
 * * <b>marginHeight</b> A altura vis�vel do papel<br>
 * * <b>pdfFontDirectory</b> O diretorio de fontes do pdf 
 * <p>
 * <b>Parametros de Banda e <i>Panel</i> interno <i>innerPanel</i></b><br>
 * * <b>class</b> uma classe que seja derivada da banda<br>
 * * <b>height</b> a altura da banda<br>
 * * <b>layout</b> o layout utilizado<br>
 * * <b>layoutInit</b> parametro de inicializa��o do layout: layout="java.awt.FlowLayout" layoutInit="LEFT"<br>
 * * <b>border</b> a borda utilizada<br>
 * * <b>borderInit</b> parametro de inicializa��o da borda<br>
 * * <b>name</b> O nome utilizado (bandEvent.getComponentByName(""))<br>
 * * <b>listener</b> O <i>listener</i> para a banda<br>
 * * <b>newPage</b> Somente para group, se inicia uma nova p�gina<br>
 * * <b>constraint</b> Somente para <i>InnerPanel</i>, a <i>constraint</i> utilizada pelo layout
 * <p>
 * <b>Parametros de Label e DbLabel <i>label e dbLabel</i></b><br>
 * * <b>name</b> O nome do label (bandEvent.getComponentByName(""))<br>
 * * <b>text</b> O texto do label<br>
 * * <b>width</b> A largura (precisa ser acompanhada pela altura)<br>
 * * <b>height</b> A altura (precisa ser acompanada pela largura)<br>
 * * <b>font</b> A nome da fonte utilizada<br>
 * * <b>fontStyle</b> O estilo da fonte <i>(bold, italic, plain)</i><br>
 * * <b>fontSize</b> O tamanho da fonte<br>
 * * <b>background</b> A cor de fundo do label<br>
 * * <b>foreground</b> A cor de frente (escrita) do label<br>
 * * <b>function</b> A fun��o utilizada pelo label <i>(NOW, DATE, TIME, PAGE_NUMBER, NUMBER_OF_PAGES, DATABASE_POSITION)</i><br>
 * * <b>format</b> O nome da classe que contenha uma fun��o de formata��o <i>format="Function$Format" formatMethod="formatMoney" alignment="right"</i><br>
 * * <b>formatInit</b> Uma vari�vel de inicio da classe de formata��o<br>
 * * <b>formatMethod</b> O nome do m�todo (recebe uma String como parametro e retorna tamb�m uma String)<br>
 * * <b>image</b> A imagem que ser� desenhada<br>
 * * <b>alignment</b> O alinhamento do texto <i>(left, right, center)</i><br>
 * * <b>constraint</b> A <i>constraint</i> utilizada pelo <i>layout</i><br>
 * * <b>border</b> A borda do label<br>
 * * <b>borderInit</b> Uma vari�vel de inicio de classe da borda<br>
 * * <b>pdfFont</b> A fonte que ser� utilizada pelo PDF<br>
 * * <b>pdfFontStyle</b> O estilo da fonte que ser� utilizada pelo PDF<br>
 * * <b>pdfFontSize</b> O tamanho da fonte que ser� utilizada pelo PDF<br>
 * * <b>field</b> Somente para DbLabel: o nome do campo do banco de dados
 * <p>
 * <b>Agrupa��o dos dados do relat�rio <i>group</i></b><br>
 * * <b>field</b> o nome do campo no banco de dados<br>
 * <i>Dentro da cl�usula <i>group</i> existem mais duas cl�usulas: header
 * e footer contendo informa��es sobre o cabe�alho e o rodap� do grupo
 * (configura��o de banda)</i>
 * <p>
 * <b>Componentes no relat�rio (fora das bandas)</b><br>
 * * <b>class</b> o nome da classe do componente (sem inicializa��o)<br>
 * * <b>x</b> a posi��o horizontal do componente<br>
 * * <b>y</b> a posi��o vertical do componente
 * <p>
 * <b>Todos os valores podem ser trocados em <i>runtime</i> por meio de vari�veis</b><br>
 * <i>data="sql:SELECT * FROM vendas WHERE data >= $datainicial$ AND data <= $datafinal$"</i><br>
 * se na inicializa��o da classe for passado como parametro um <i>HashMap</i> contendo
 * as vari�veis que dever�o ser trocadas, e "datainicial" e "datafinal" fizerem parte
 * destas vari�veis, as mesmas ser�o trocadas antes de serem executadas.
 * <p>
 * <b>Utilize a tag &lt;!include file=""&gt; para incluir os 
 * dados de um arquivo separado no xml</b>
 *
 * @author  saci
 */
public class XmlReader {

    private Document document;
    private NodeList bpNode;
    private HashMap variables;
    private Font fonte = new Font("Arial", Font.PLAIN, 9);

    /**
     * Cria uma nova inst�ncia da classe.
     *
     * @param xml o XML a ser processado
     */
    public XmlReader(String xml) throws SAXException, IOException {
        this(xml, null);
    }

    /**
     * Cria uma nova inst�ncia da classe.
     *
     * @param xml o XML a ser processado
     * @param variables as vari�veis do XML
     */
    public XmlReader(String xml, java.util.HashMap variables) throws SAXException, IOException {
        DOMParser parser = new DOMParser();

        this.variables = variables;

        parser.parse(new InputSource(new StringReader(checkInc(xml))));

        this.document = parser.getDocument();

        if (document.getElementsByTagName("saci") != null && document.getElementsByTagName("saci").item(0) != null) {
            this.bpNode = document.getElementsByTagName("saci").item(0).getChildNodes();

        } else {
            throw new SAXException("Invalid XML file. Main tag \"saci\" not found.");
        }
    }

    private String checkInc(String xml) {
        String temp;

        if (xml.indexOf("<!include") > -1) {
            temp = xml.substring(xml.indexOf("<!include") + 9);
            temp = temp.substring(0, temp.indexOf(">")).trim(); //file="myFile.xml"

            if (temp.indexOf("file") == -1) {
                throw new RuntimeException("Include clause is invalid");
            }

            if (temp.indexOf("\"") == -1 && temp.indexOf("'") == -1) {
                throw new RuntimeException("Include clause is invalid");
            }

            temp = temp.substring(6); // 6 - file="
            temp = temp.substring(0, temp.length() - 1);

            try {
                BufferedReader in = new BufferedReader(new FileReader(checkVariables(temp)));

                StringBuffer newXml = new StringBuffer();

                while (in.ready()) {
                    newXml.append(in.readLine());
                }

                String tmp = xml.substring(xml.indexOf("<!include") + 9);
                int length = tmp.indexOf(">");
                temp = xml.substring(0, xml.indexOf("<!include")); // copy the begin
                xml = temp + newXml + xml.substring(xml.indexOf("<!include") + 10 + length);

                in.close();
            } catch (Exception e) {
                throw new RuntimeException(e.toString());
            }
        }

        return xml.indexOf("<!include") > -1 ? checkInc(xml) : xml;
    }

    /**
     * Retorna a orienta��o do papel
     */
    public int getOrientation() {
        Node node = findNode(bpNode, "report");

        if (node.getAttributes().getNamedItem("orientation") != null) {
            String s = node.getAttributes().getNamedItem("orientation").getNodeValue();

            if (s.equalsIgnoreCase("portrait") || s.equalsIgnoreCase("1")) {
                return ReportManager.PORTRAIT;
            } else if (s.equalsIgnoreCase("landscape") || s.equalsIgnoreCase("2")) {
                return ReportManager.LANDSCAPE;
            }
        }

        return ReportManager.PORTRAIT;
    }

    /**
     * Retorna o tamanho do papel a ser impresso
     */
    public ReportManager.ReportPaper getPaper() {
        Node node = findNode(bpNode, "report");

        double width, height, x, y, marginWidth, marginHeight;
        width = height = x = y = marginWidth = marginHeight = -1;

        if (node.getAttributes().getNamedItem("paper") != null) {
            String comp = checkVariables(node.getAttributes().getNamedItem("paper").getNodeValue());

            if (comp.equalsIgnoreCase("a4")) {
                return ReportManager.A4;
            } else if (comp.equalsIgnoreCase("letter")) {
                return ReportManager.LETTER;
            } else if (comp.equalsIgnoreCase("a3")) {
                return ReportManager.A3;
            } else if (comp.equalsIgnoreCase("legal")) {
                return ReportManager.LEGAL;
            }
        } else {
            if (node.getAttributes().getNamedItem("width") != null) {
                width = Double.parseDouble(checkVariables(node.getAttributes().getNamedItem("width").getNodeValue()));
            }

            if (node.getAttributes().getNamedItem("height") != null) {
                height = Double.parseDouble(checkVariables(node.getAttributes().getNamedItem("height").getNodeValue()));
            }

            if (node.getAttributes().getNamedItem("marginX") != null) {
                x = Double.parseDouble(checkVariables(node.getAttributes().getNamedItem("marginX").getNodeValue()));
            }

            if (node.getAttributes().getNamedItem("marginY") != null) {
                y = Double.parseDouble(checkVariables(node.getAttributes().getNamedItem("marginY").getNodeValue()));
            }

            if (node.getAttributes().getNamedItem("marginWidth") != null) {
                marginWidth = Double.parseDouble(checkVariables(node.getAttributes().getNamedItem("marginWidth").getNodeValue()));
            }

            if (node.getAttributes().getNamedItem("marginHeight") != null) {
                marginHeight = Double.parseDouble(checkVariables(node.getAttributes().getNamedItem("marginHeight").getNodeValue()));
            }

            if (width > -1 && height > -1) {
                if (x > -1 && y > -1 && marginWidth > -1 && marginHeight > -1) {
                    return new ReportManager.ReportPaper(width, height, x, y, marginWidth, marginHeight);
                } else if (x > -1 && y > -1) {
                    return new ReportManager.ReportPaper(width, height, x, y);
                } else {
                    return new ReportManager.ReportPaper(width, height, (width > 50) ? 30 : 0, (height > 50) ? 30 : 0);
                }
            }
        }

        return ReportManager.A4;
    }

    /**
     * Retorna a instru��o SQL
     */
    public String getSQL() {
        Node node = findNode(bpNode, "report");

        if (node != null && node.getAttributes().getNamedItem("data") != null) {
            String s = checkVariables(node.getAttributes().getNamedItem("data").getNodeValue());

            if (s.toLowerCase().startsWith("sql:")) {
                return s.substring(4);
            }
        }

        return null;
    }

    /**
     * Retorna o diretorio de fontes
     */
    public String getFontDirectory() {
        Node node = findNode(bpNode, "report");

        if (node != null && node.getAttributes().getNamedItem("pdfFontDirectory") != null) {
            String s = checkVariables(node.getAttributes().getNamedItem("pdfFontDirectory").getNodeValue());
            return s;
        }

        return null;
    }

    /**
     * Retorna um vetor contendo os componentes do relat�rio (fora das bandas)
     */
    public Vector getComponentsInReport() {
        Node node = findNode(bpNode, "report");
        Vector vector = new Vector();

        try {
            if (node != null) {
                node = findNode(node.getChildNodes(), "componentsInReport");

                if (node != null && node.hasChildNodes()) {
                    NodeList list = node.getChildNodes();

                    for (int i = 0; i < list.getLength(); i++) {
                        if (list.item(i).getAttributes() != null && list.item(i).getAttributes().getNamedItem("class") != null) {
                            Component comp = (Component) Class.forName(checkVariables(list.item(i).getAttributes().getNamedItem("class").getNodeValue())).newInstance();

                            if (list.item(i).getAttributes().getNamedItem("x") != null) {
                                comp.setLocation(Integer.parseInt(checkVariables(list.item(i).getAttributes().getNamedItem("x").getNodeValue())), comp.getLocation().y);
                            }

                            if (list.item(i).getAttributes().getNamedItem("y") != null) {
                                comp.setLocation(comp.getLocation().x, Integer.parseInt(checkVariables(list.item(i).getAttributes().getNamedItem("y").getNodeValue())));
                            }

                            vector.addElement(comp);
                        }
                    }
                }
            }

            if (vector.size() > 0) {
                return vector;
            }
        } catch (Exception e) {
            throw new RuntimeException(e.toString());
        }

        return null;
    }

    /**
     * Retorna a Banda de Detalhes <i>DetailBand</i> configurada no XML
     */
    public DetailBand getDetailBand() {
        Node node = findNode(bpNode, "report");

        if (node != null) {
            NodeList list = node.getChildNodes();
            node = findNode(list, "detail");

            if (node != null) {
                list = node.getChildNodes();
                Component[] c;

                DetailBand p;

                if (node.getAttributes().getNamedItem("class") != null) {
                    try {
                        p = (DetailBand) Class.forName(checkVariables(node.getAttributes().getNamedItem("class").getNodeValue())).newInstance();
                    } catch (Exception e) {
                        throw new RuntimeException(e.toString());
                    }
                } else {
                    p = new DetailBand();
                }

                if (node.getAttributes().getNamedItem("layout") != null) {
                    c = getComponents(list, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                    preparePanel(p, c, node, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                } else {
                    c = getComponents(list, p.getLayout().getClass().toString().substring(6));
                    preparePanel(p, c, node, p.getLayout().getClass().toString().substring(6));
                }

                if (node.getAttributes().getNamedItem("border") != null) {
                    if (node.getAttributes().getNamedItem("borderInit") != null) {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                    } else {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), null));
                    }
                }

                if (node.getAttributes().getNamedItem("listener") != null) {
                    if (node.getAttributes().getNamedItem("listenerInit") != null) {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("listenerInit").getNodeValue())));
                    } else {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), null));
                    }
                }

                return p;
            }
        }

        return null;
    }

    /**
     * Retorna o cabe�alho <i>HeaderBand</i>
     */
    public HeaderBand getHeaderBand() {
        Node node = findNode(bpNode, "report");

        if (node != null) {
            NodeList list = node.getChildNodes();
            node = findNode(list, "header");

            if (node != null) {
                list = node.getChildNodes();
                Component[] c;

                HeaderBand p;

                if (node.getAttributes().getNamedItem("class") != null) {
                    try {
                        p = (HeaderBand) Class.forName(checkVariables(node.getAttributes().getNamedItem("class").getNodeValue())).newInstance();
                    } catch (Exception e) {
                        throw new RuntimeException(e.toString());
                    }
                } else {
                    p = new HeaderBand();
                }

                if (node.getAttributes().getNamedItem("layout") != null) {
                    c = getComponents(list, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                    preparePanel(p, c, node, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                } else {
                    c = getComponents(list, p.getLayout().getClass().toString().substring(6));
                    preparePanel(p, c, node, p.getLayout().getClass().toString().substring(6));
                }

                if (node.getAttributes().getNamedItem("border") != null) {
                    if (node.getAttributes().getNamedItem("borderInit") != null) {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                    } else {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), null));
                    }
                }

                if (node.getAttributes().getNamedItem("listener") != null) {
                    if (node.getAttributes().getNamedItem("listenerInit") != null) {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("listenerInit").getNodeValue())));
                    } else {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), null));
                    }
                }

                return p;
            }
        }

        return null;
    }

    /**
     * Retorna o rodap� <i>FooterBand</i>
     */
    public FooterBand getFooterBand() {
        Node node = findNode(bpNode, "report");

        if (node != null) {
            NodeList list = node.getChildNodes();
            node = findNode(list, "footer");

            if (node != null) {
                list = node.getChildNodes();
                Component[] c;

                FooterBand p;

                if (node.getAttributes().getNamedItem("class") != null) {
                    try {
                        p = (FooterBand) Class.forName(checkVariables(node.getAttributes().getNamedItem("class").getNodeValue())).newInstance();
                    } catch (Exception e) {
                        throw new RuntimeException(e.toString());
                    }
                } else {
                    p = new FooterBand();
                }

                if (node.getAttributes().getNamedItem("layout") != null) {
                    c = getComponents(list, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                    preparePanel(p, c, node, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                } else {
                    c = getComponents(list, p.getLayout().getClass().toString().substring(6));
                    preparePanel(p, c, node, p.getLayout().getClass().toString().substring(6));
                }

                if (node.getAttributes().getNamedItem("border") != null) {
                    if (node.getAttributes().getNamedItem("borderInit") != null) {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                    } else {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), null));
                    }
                }

                if (node.getAttributes().getNamedItem("listener") != null) {
                    if (node.getAttributes().getNamedItem("listenerInit") != null) {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("listenerInit").getNodeValue())));
                    } else {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), null));
                    }
                }

                return p;
            }
        }

        return null;
    }

    /**
     * Retorna o t�tulo <i>TitleBand</i>
     */
    public TitleBand getTitleBand() {
        Node node = findNode(bpNode, "report");

        if (node != null) {
            NodeList list = node.getChildNodes();
            node = findNode(list, "title");

            if (node != null) {
                list = node.getChildNodes();
                Component[] c;

                TitleBand p;

                if (node.getAttributes().getNamedItem("class") != null) {
                    try {
                        p = (TitleBand) Class.forName(checkVariables(node.getAttributes().getNamedItem("class").getNodeValue())).newInstance();
                    } catch (Exception e) {
                        throw new RuntimeException(e.toString());
                    }
                } else {
                    p = new TitleBand();
                }

                if (node.getAttributes().getNamedItem("layout") != null) {
                    c = getComponents(list, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                    preparePanel(p, c, node, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                } else {
                    c = getComponents(list, p.getLayout().getClass().toString().substring(6));
                    preparePanel(p, c, node, p.getLayout().getClass().toString().substring(6));
                }

                if (node.getAttributes().getNamedItem("border") != null) {
                    if (node.getAttributes().getNamedItem("borderInit") != null) {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                    } else {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), null));
                    }
                }

                if (node.getAttributes().getNamedItem("listener") != null) {
                    if (node.getAttributes().getNamedItem("listenerInit") != null) {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("listenerInit").getNodeValue())));
                    } else {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), null));
                    }
                }

                return p;
            }
        }

        return null;
    }

    /**
     * Retorna o sum�rio do relat�rio <i>SummaryBand</i>
     */
    public SummaryBand getSummaryBand() {
        Node node = findNode(bpNode, "report");

        if (node != null) {
            NodeList list = node.getChildNodes();
            node = findNode(list, "summary");

            if (node != null) {
                list = node.getChildNodes();
                Component[] c;

                SummaryBand p;

                if (node.getAttributes().getNamedItem("class") != null) {
                    try {
                        p = (SummaryBand) Class.forName(checkVariables(node.getAttributes().getNamedItem("class").getNodeValue())).newInstance();
                    } catch (Exception e) {
                        throw new RuntimeException(e.toString());
                    }
                } else {
                    p = new SummaryBand();
                }

                if (node.getAttributes().getNamedItem("layout") != null) {
                    c = getComponents(list, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                    preparePanel(p, c, node, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                } else {
                    c = getComponents(list, p.getLayout().getClass().toString().substring(6));
                    preparePanel(p, c, node, p.getLayout().getClass().toString().substring(6));
                }

                if (node.getAttributes().getNamedItem("border") != null) {
                    if (node.getAttributes().getNamedItem("borderInit") != null) {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                    } else {
                        p.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), null));
                    }
                }

                if (node.getAttributes().getNamedItem("newPage") != null) {
                    if (checkVariables(node.getAttributes().getNamedItem("newPage").getNodeValue()).equalsIgnoreCase("true")) {
                        p.setCreateNewPage(true);
                    } else {
                        p.setCreateNewPage(false);
                    }
                }

                if (node.getAttributes().getNamedItem("listener") != null) {
                    if (node.getAttributes().getNamedItem("listenerInit") != null) {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("listenerInit").getNodeValue())));
                    } else {
                        p.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), null));
                    }
                }

                return p;
            }
        }

        return null;
    }

    /**
     * Retorna a agrupa��o dos dados do relat�rio <i>Group</i>
     */
    public Group getGroup() {
        Node node = findNode(bpNode, "report");

        if (node != null) {
            NodeList list = node.getChildNodes();
            node = findNode(list, "group");

            if (node != null) {
                Component[] c;
                NodeList groupList = node.getChildNodes();

                if (node.getAttributes().getNamedItem("field") != null) {
                    String field = checkVariables(node.getAttributes().getNamedItem("field").getNodeValue());
                    node = findNode(groupList, "footer");
                    GroupFooterBand fb;
                    GroupHeaderBand hb;

                    if (node.getAttributes().getNamedItem("class") != null) {
                        try {
                            fb = (GroupFooterBand) Class.forName(checkVariables(node.getAttributes().getNamedItem("class").getNodeValue())).newInstance();
                        } catch (Exception e) {
                            throw new RuntimeException(e.toString());
                        }
                    } else {
                        fb = new GroupFooterBand();
                    }

                    if (node != null) {
                        list = node.getChildNodes();

                        if (node.getAttributes().getNamedItem("layout") != null) {
                            c = getComponents(list, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                            preparePanel(fb, c, node, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                        } else {
                            c = getComponents(list, fb.getLayout().getClass().toString().substring(6));
                            preparePanel(fb, c, node, fb.getLayout().getClass().toString().substring(6));
                        }

                        if (node.getAttributes().getNamedItem("border") != null) {
                            if (node.getAttributes().getNamedItem("borderInit") != null) {
                                fb.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                            } else {
                                fb.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), null));
                            }
                        }
                    }

                    if (node.getAttributes().getNamedItem("listener") != null) {
                        if (node.getAttributes().getNamedItem("listenerInit") != null) {
                            fb.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("listenerInit").getNodeValue())));
                        } else {
                            fb.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), null));
                        }
                    }

                    node = findNode(groupList, "header");

                    if (node.getAttributes().getNamedItem("class") != null) {
                        try {
                            hb = (GroupHeaderBand) Class.forName(checkVariables(node.getAttributes().getNamedItem("class").getNodeValue())).newInstance();
                        } catch (Exception e) {
                            throw new RuntimeException(e.toString());
                        }
                    } else {
                        hb = new GroupHeaderBand();
                    }

                    if (node != null) {
                        list = node.getChildNodes();

                        if (node.getAttributes().getNamedItem("layout") != null) {
                            c = getComponents(list, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                            preparePanel(hb, c, node, checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()));
                        } else {
                            c = getComponents(list, hb.getLayout().getClass().toString().substring(6));
                            preparePanel(hb, c, node, hb.getLayout().getClass().toString().substring(6));
                        }

                        if (node.getAttributes().getNamedItem("border") != null) {
                            if (node.getAttributes().getNamedItem("borderInit") != null) {
                                hb.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                            } else {
                                hb.setBorder(getBorder(checkVariables(node.getAttributes().getNamedItem("border").getNodeValue()), null));
                            }
                        }
                    }

                    if (node.getAttributes().getNamedItem("listener") != null) {
                        if (node.getAttributes().getNamedItem("listenerInit") != null) {
                            hb.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), checkVariables(node.getAttributes().getNamedItem("listenerInit").getNodeValue())));
                        } else {
                            hb.addBandListener(getBandListener(checkVariables(node.getAttributes().getNamedItem("listener").getNodeValue()), null));
                        }
                    }

                    return new Group(field, hb, fb);
                }
            }
        }

        return null;
    }

    /**
     * Retorna a conex�o com banco de dados configurada no XML
     */
    public Connection getConnection() {
        Connection connection = null;
        NodeList conn = null;
        Node node;

        node = findNode(bpNode, "connection");

        if (node != null) {
            conn = node.getChildNodes();
        }

        String url, driver, user, password;
        url = driver = user = password = null;

        if (conn != null) {
            node = findNode(conn, "url");

            if (node != null) {
                if (node.hasChildNodes() && node.getChildNodes().item(0) != null && checkVariables(node.getChildNodes().item(0).getNodeValue()) != null) {
                    url = checkVariables(node.getChildNodes().item(0).getNodeValue());
                } else if (node.getAttributes().getNamedItem("value") != null) {
                    url = checkVariables(node.getAttributes().getNamedItem("value").getNodeValue());
                }
            }

            node = findNode(conn, "driver");

            if (node != null) {
                if (node.hasChildNodes() && node.getChildNodes().item(0) != null && checkVariables(node.getChildNodes().item(0).getNodeValue()) != null) {
                    driver = checkVariables(node.getChildNodes().item(0).getNodeValue());
                } else if (node.getAttributes().getNamedItem("value") != null) {
                    driver = checkVariables(node.getAttributes().getNamedItem("value").getNodeValue());
                }
            }

            node = findNode(conn, "user");

            if (node != null) {
                if (node.hasChildNodes() && node.getChildNodes().item(0) != null && checkVariables(node.getChildNodes().item(0).getNodeValue()) != null) {
                    user = checkVariables(node.getChildNodes().item(0).getNodeValue());
                } else if (node.getAttributes().getNamedItem("value") != null) {
                    user = checkVariables(node.getAttributes().getNamedItem("value").getNodeValue());
                }
            }

            node = findNode(conn, "password");

            if (node != null) {
                if (node.hasChildNodes() && node.getChildNodes().item(0) != null && checkVariables(node.getChildNodes().item(0).getNodeValue()) != null) {
                    password = checkVariables(node.getChildNodes().item(0).getNodeValue());
                } else if (node.getAttributes().getNamedItem("value") != null) {
                    password = checkVariables(node.getAttributes().getNamedItem("value").getNodeValue());
                }
            }
        }

        if (url != null && driver != null) {
            try {
                Class.forName(driver);

                if (user == null && password == null) {
                    connection = DriverManager.getConnection(url);
                } else {
                    connection = DriverManager.getConnection(url, user, password);
                }
            } catch (Exception e) {
                throw new RuntimeException(e.toString());
            }
        }

        return connection;
    }

    /**
     * Prepara um painel <i>ReportPanel</i>
     */
    private void preparePanel(ReportPanel panel, Component[] c, Node node, String mainLayout) {
        Node temp;

        if ((temp = node.getAttributes().getNamedItem("name")) != null) {
            panel.setName(checkVariables(temp.getNodeValue()));
        }

        if ((temp = node.getAttributes().getNamedItem("constraint")) != null) {
            panel.setConstraint(getConstraint(mainLayout, checkVariables(temp.getNodeValue())));
        }

        if ((temp = node.getAttributes().getNamedItem("height")) != null) {
            panel.setSize(panel.getWidth(), Integer.parseInt(checkVariables(temp.getNodeValue())));
        }

        if ((temp = node.getAttributes().getNamedItem("width")) != null) {
            panel.setSize(Integer.parseInt(checkVariables(temp.getNodeValue())), panel.getHeight());
        }

        if ((temp = node.getAttributes().getNamedItem("layout")) != null) {
            if (node.getAttributes().getNamedItem("layoutInit") != null) {
                panel.setLayout(getLayout(checkVariables(temp.getNodeValue()), checkVariables(node.getAttributes().getNamedItem("layoutInit").getNodeValue())));
            } else {
                panel.setLayout(getLayout(checkVariables(temp.getNodeValue()), null));
            }
        }

        if ((temp = node.getAttributes().getNamedItem("border")) != null) {
            if (node.getAttributes().getNamedItem("borderInit") != null) {
                panel.setBorder(getBorder(checkVariables(temp.getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
            } else {
                panel.setBorder(getBorder(checkVariables(temp.getNodeValue()), null));
            }
        }

        if (c != null) {
            for (int j = 0; j < c.length; j++) {
                if (c[j] != null) {
                    if (c[j] instanceof Label) {
                        if (((Label) c[j]).getConstraint() != null) {
                            panel.add(c[j], ((Label) c[j]).getConstraint());
                        } else {
                            panel.add(c[j]);
                        }
                    } else if (c[j] instanceof ReportPanel) {
                        if (((ReportPanel) c[j]).getConstraint() != null) {
                            panel.add(c[j], ((ReportPanel) c[j]).getConstraint());
                        } else {
                            panel.add(c[j]);
                        }
                    } else {
                        panel.add(c[j]);
                    }
                }
            }
        }
    }

    /**
     * Retorna os componentes dentro da banda
     */
    private Component[] getComponents(NodeList list, String mainLayout) {
        if (list.getLength() > 0) {
            Component[] result = new Component[list.getLength()];
            Node node, temp;

            for (int i = 0; i < result.length; i++) {
                node = list.item(i);

                if (node.getNodeName().equals("innerPanel")) { // Inner Panel
                    InnerPanel inner;

                    if ((temp = node.getAttributes().getNamedItem("class")) != null) {
                        try {
                            inner = (InnerPanel) Class.forName(checkVariables(temp.getNodeValue())).newInstance();
                        } catch (Exception e) {
                            throw new RuntimeException(e.toString());
                        }
                    } else {
                        inner = new InnerPanel();
                    }

                    /*if ((temp = node.getAttributes().getNamedItem("name")) != null)
                    lbl.setName(checkVariables(temp.getNodeValue()));
                    
                    if ((temp = node.getAttributes().getNamedItem("border")) != null) {
                    if (node.getAttributes().getNamedItem("borderInit") != null)
                    inner.setBorder(getBorder(checkVariables(temp.getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                    else
                    inner.setBorder(getBorder(checkVariables(temp.getNodeValue()), null));
                    }*/

                    Component[] c = getComponents(node.getChildNodes(), (node.getAttributes().getNamedItem("layout") != null ? checkVariables(node.getAttributes().getNamedItem("layout").getNodeValue()) : null));

                    preparePanel(inner, c, node, mainLayout);

                    result[i] = inner;
                } else if (node.getNodeName().equals("label") || node.getNodeName().equals("dbLabel")) {
                    Label lbl;

                    if (node.getNodeName().equals("label")) {
                        lbl = new Label();
                    } else {
                        lbl = new DbLabel();
                    }

                    lbl.setFont(fonte);

                    if ((temp = node.getAttributes().getNamedItem("name")) != null) {
                        lbl.setName(checkVariables(temp.getNodeValue()));
                    }

                    if ((temp = node.getAttributes().getNamedItem("text")) != null) {
                        lbl.setText(checkVariables(temp.getNodeValue()));
                    }

                    if ((temp = node.getAttributes().getNamedItem("width")) != null) {
                        lbl.setPreferredSize(new Dimension(Integer.parseInt(checkVariables(temp.getNodeValue())), lbl.getPreferredSize().height));
                        lbl.setSize(lbl.getPreferredSize());
                    }

                    if ((temp = node.getAttributes().getNamedItem("height")) != null) {
                        lbl.setPreferredSize(new Dimension(lbl.getPreferredSize().width, Integer.parseInt(checkVariables(temp.getNodeValue()))));
                        lbl.setSize(lbl.getPreferredSize());
                    }

                    if ((temp = node.getAttributes().getNamedItem("font")) != null) {
                        String s = checkVariables(temp.getNodeValue());

                        if (s.toLowerCase().endsWith(".ttf")) {
                            // carrega a fonte
                            try {
                                Font f = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream(s));
                                lbl.setFont(f.deriveFont(lbl.getFont().getStyle(), lbl.getFont().getSize()));
                            } catch (FileNotFoundException e) {
                                throw new RuntimeException("Font file not found: " + s);
                            } catch (FontFormatException e) {
                                throw new RuntimeException("The font has an invalid format (not True Type)");
                            } catch (IOException e) {
                                throw new RuntimeException("Error opening font file");
                            }
                        } else {
                            lbl.setFont(new Font(s, lbl.getFont().getStyle(), lbl.getFont().getSize()));
                        }
                    }

                    if (node.getAttributes().getNamedItem("fontStyle") != null) {
                        if (checkVariables(node.getAttributes().getNamedItem("fontStyle").getNodeValue()).toLowerCase().indexOf("bold") > -1 && checkVariables(node.getAttributes().getNamedItem("fontStyle").getNodeValue()).toLowerCase().indexOf("italic") > -1) {
                            lbl.setFont(new Font(lbl.getFont().getFontName(), Font.BOLD | Font.ITALIC, lbl.getFont().getSize()));
                        } else {
                            if (checkVariables(node.getAttributes().getNamedItem("fontStyle").getNodeValue()).toLowerCase().indexOf("bold") > -1) {
                                lbl.setFont(new Font(lbl.getFont().getFontName(), Font.BOLD, lbl.getFont().getSize()));
                            } else if (checkVariables(node.getAttributes().getNamedItem("fontStyle").getNodeValue()).toLowerCase().indexOf("italic") > -1) {
                                lbl.setFont(new Font(lbl.getFont().getFontName(), Font.ITALIC, lbl.getFont().getSize()));
                            }
                        }
                    }

                    if ((temp = node.getAttributes().getNamedItem("fontSize")) != null) {
                        lbl.setFont(new Font(lbl.getFont().getFontName(), lbl.getFont().getStyle(), Integer.parseInt(checkVariables(temp.getNodeValue()))));
                    }

                    if ((temp = node.getAttributes().getNamedItem("pdfFont")) != null) {
                        lbl.setPDFFont(new Font(checkVariables(temp.getNodeValue()), lbl.getFont().getStyle(), lbl.getFont().getSize()));
                    }

                    if (node.getAttributes().getNamedItem("pdfFontStyle") != null) {
                        if (checkVariables(node.getAttributes().getNamedItem("pdfFontStyle").getNodeValue()).toLowerCase().indexOf("bold") > -1 && checkVariables(node.getAttributes().getNamedItem("pdfFontStyle").getNodeValue()).toLowerCase().indexOf("italic") > -1) {
                            lbl.setPDFFont(new Font(lbl.getPDFFont().getFontName(), Font.BOLD | Font.ITALIC, lbl.getPDFFont().getSize()));
                        } else {
                            if (checkVariables(node.getAttributes().getNamedItem("pdfFontStyle").getNodeValue()).toLowerCase().indexOf("bold") > -1) {
                                lbl.setPDFFont(new Font(lbl.getPDFFont().getFontName(), Font.BOLD, lbl.getPDFFont().getSize()));
                            } else if (checkVariables(node.getAttributes().getNamedItem("pdfFontStyle").getNodeValue()).toLowerCase().indexOf("italic") > -1) {
                                lbl.setPDFFont(new Font(lbl.getPDFFont().getFontName(), Font.ITALIC, lbl.getPDFFont().getSize()));
                            }
                        }
                    }

                    if ((temp = node.getAttributes().getNamedItem("pdfFontSize")) != null) {
                        lbl.setPDFFont(new Font(lbl.getPDFFont().getFontName(), lbl.getPDFFont().getStyle(), Integer.parseInt(checkVariables(temp.getNodeValue()))));
                    }

                    if ((temp = node.getAttributes().getNamedItem("background")) != null) {
                        lbl.setBackground(getColor(checkVariables(temp.getNodeValue())) != null ? getColor(checkVariables(temp.getNodeValue())) : Color.white);
                    }

                    if ((temp = node.getAttributes().getNamedItem("foreground")) != null) {
                        lbl.setForeground(getColor(checkVariables(temp.getNodeValue())) != null ? getColor(checkVariables(temp.getNodeValue())) : Color.black);
                    }

                    if ((temp = node.getAttributes().getNamedItem("function")) != null) {
                        lbl.setFunction(getFunctionNumber(checkVariables(temp.getNodeValue())));
                    }

                    if ((temp = node.getAttributes().getNamedItem("format")) != null) {
                        String format = checkVariables(temp.getNodeValue());
                        String formatInit = null;
                        String formatMethod = null;

                        if ((temp = node.getAttributes().getNamedItem("formatInit")) != null) {
                            formatInit = checkVariables(temp.getNodeValue());
                        }

                        if ((temp = node.getAttributes().getNamedItem("formatMethod")) != null) {
                            formatMethod = checkVariables(temp.getNodeValue());
                        }

                        if (formatMethod != null) {
                            lbl.setOtherFunction(checkVariables(format), checkVariables(formatInit), checkVariables(formatMethod));
                        }
                    }

                    if ((temp = node.getAttributes().getNamedItem("image")) != null) {
                        try {
                            lbl.setIcon(new ImageIcon(new URL(checkVariables(temp.getNodeValue()))));
                        } catch (Exception e) {
                            throw new RuntimeException(e.toString());
                        }
                    }

                    if ((temp = node.getAttributes().getNamedItem("alignment")) != null) {
                        if (checkVariables(temp.getNodeValue()).equalsIgnoreCase("left")) {
                            lbl.setHorizontalAlignment(Label.LEFT);
                        } else if (checkVariables(temp.getNodeValue()).equalsIgnoreCase("right")) {
                            lbl.setHorizontalAlignment(Label.RIGHT);
                        } else if (checkVariables(temp.getNodeValue()).equalsIgnoreCase("center")) {
                            lbl.setHorizontalAlignment(Label.CENTER);
                        } else if (checkVariables(temp.getNodeValue()).equalsIgnoreCase("leading")) {
                            lbl.setHorizontalAlignment(Label.LEADING);
                        }
                    }

                    if ((temp = node.getAttributes().getNamedItem("constraint")) != null) {
                        lbl.setConstraint(getConstraint(mainLayout, checkVariables(temp.getNodeValue())));
                    }

                    if ((temp = node.getAttributes().getNamedItem("border")) != null) {
                        if (node.getAttributes().getNamedItem("borderInit") != null) {
                            lbl.setBorder(getBorder(checkVariables(temp.getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                        } else {
                            lbl.setBorder(getBorder(checkVariables(temp.getNodeValue()), null));
                        }
                    }

                    if ((temp = node.getAttributes().getNamedItem("field")) != null && lbl instanceof DbLabel) {
                        ((DbLabel) lbl).setField(checkVariables(temp.getNodeValue()));
                    }

                    result[i] = lbl;
                }
                /*else if (node.getNodeName().equals("label")) {
                Label lbl = new Label();

                lbl.setFont(new Font("Verdana", Font.PLAIN, 10));

                if ((temp = node.getAttributes().getNamedItem("name")) != null)
                lbl.setName(checkVariables(temp.getNodeValue()));

                if ((temp = node.getAttributes().getNamedItem("text")) != null)
                lbl.setText(checkVariables(temp.getNodeValue()));

                if ((temp = node.getAttributes().getNamedItem("width")) != null) {
                lbl.setPreferredSize(new Dimension(Integer.parseInt(checkVariables(temp.getNodeValue())), lbl.getPreferredSize().height));
                lbl.setSize(lbl.getPreferredSize());
                }

                if ((temp = node.getAttributes().getNamedItem("height")) != null) {
                lbl.setPreferredSize(new Dimension(lbl.getPreferredSize().width, Integer.parseInt(checkVariables(temp.getNodeValue()))));
                lbl.setSize(lbl.getPreferredSize());
                }

                if ((temp = node.getAttributes().getNamedItem("font")) != null)
                lbl.setFont(new Font(checkVariables(temp.getNodeValue()), lbl.getFont().getStyle(), lbl.getFont().getSize()));

                if (node.getAttributes().getNamedItem("fontStyle") != null) {
                if (checkVariables(node.getAttributes().getNamedItem("fontStyle").getNodeValue()).toLowerCase().indexOf("bold") > -1 && checkVariables(node.getAttributes().getNamedItem("fontStyle").getNodeValue()).toLowerCase().indexOf("italic") > -1)
                lbl.setFont(new Font(lbl.getFont().getFontName(), Font.BOLD | Font.ITALIC, lbl.getFont().getSize()));
                else {
                if (checkVariables(node.getAttributes().getNamedItem("fontStyle").getNodeValue()).toLowerCase().indexOf("bold") > -1)
                lbl.setFont(new Font(lbl.getFont().getFontName(), Font.BOLD, lbl.getFont().getSize()));
                else if (checkVariables(node.getAttributes().getNamedItem("fontStyle").getNodeValue()).toLowerCase().indexOf("italic") > -1)
                lbl.setFont(new Font(lbl.getFont().getFontName(), Font.ITALIC, lbl.getFont().getSize()));
                }
                }

                if ((temp = node.getAttributes().getNamedItem("fontSize")) != null)
                lbl.setFont(new Font(lbl.getFont().getFontName(), lbl.getFont().getStyle(), Integer.parseInt(temp.getNodeValue())));

                if ((temp = node.getAttributes().getNamedItem("background")) != null)
                lbl.setBackground(getColor(checkVariables(temp.getNodeValue())) != null ? getColor(checkVariables(temp.getNodeValue())) : Color.white);

                if ((temp = node.getAttributes().getNamedItem("foreground")) != null)
                lbl.setForeground(getColor(checkVariables(temp.getNodeValue())) != null ? getColor(checkVariables(temp.getNodeValue())) : Color.black);

                if ((temp = node.getAttributes().getNamedItem("function")) != null)
                lbl.setFunction(getFunctionNumber(checkVariables(temp.getNodeValue())));

                if ((temp = node.getAttributes().getNamedItem("format")) != null) {
                String format = temp.getNodeValue();
                String formatInit = null;
                String formatMethod = null;

                if ((temp = node.getAttributes().getNamedItem("formatInit")) != null)
                formatInit = temp.getNodeValue();

                if ((temp = node.getAttributes().getNamedItem("formatMethod")) != null)
                formatMethod = temp.getNodeValue();

                if (formatMethod != null)
                lbl.setOtherFunction(checkVariables(format), checkVariables(formatInit), checkVariables(formatMethod));
                }

                if ((temp = node.getAttributes().getNamedItem("image")) != null) {
                try {
                lbl.setIcon(new ImageIcon(new URL(checkVariables(temp.getNodeValue()))));
                }
                catch (Exception e) {
                throw new RuntimeException(e.toString());
                }
                }

                if ((temp = node.getAttributes().getNamedItem("alignment")) != null) {
                if (checkVariables(temp.getNodeValue()).equalsIgnoreCase("left")) {
                lbl.setHorizontalAlignment(lbl.LEFT);
                }
                else if (checkVariables(temp.getNodeValue()).equalsIgnoreCase("right")) {
                lbl.setHorizontalAlignment(lbl.RIGHT);
                }
                else if (checkVariables(temp.getNodeValue()).equalsIgnoreCase("center")) {
                lbl.setHorizontalAlignment(lbl.CENTER);
                }
                else if (checkVariables(temp.getNodeValue()).equalsIgnoreCase("leading")) {
                lbl.setHorizontalAlignment(lbl.LEADING);
                }
                }

                if ((temp = node.getAttributes().getNamedItem("constraint")) != null)
                lbl.setConstraint(getConstraint(mainLayout, checkVariables(temp.getNodeValue())));

                if ((temp = node.getAttributes().getNamedItem("border")) != null) {
                if (node.getAttributes().getNamedItem("borderInit") != null)
                lbl.setBorder(getBorder(checkVariables(temp.getNodeValue()), checkVariables(node.getAttributes().getNamedItem("borderInit").getNodeValue())));
                else
                lbl.setBorder(getBorder(checkVariables(temp.getNodeValue()), null));
                }

                result[i] = lbl;
                }*/
            }

            return result;
        } else {
            return null;
        }
    }

    private Border getBorder(String border, String init) {
        try {
            if (init != null) {
                Object o = getConstraint(border, init);
                Class cl;
                if (o instanceof Integer) {
                    cl = int.class;
                } else if (o instanceof Boolean) {
                    cl = boolean.class;
                } else if (o instanceof Double) {
                    cl = double.class;
                } else if (o instanceof Float) {
                    cl = float.class;
                } else if (o instanceof Byte) {
                    cl = byte.class;
                } else if (o instanceof Character) {
                    cl = char.class;
                } else {
                    cl = o.getClass();
                }

                Constructor c = Class.forName(border).getConstructor(new Class[]{cl});

                return (Border) c.newInstance(new Object[]{o});

                //return new java.awt.FlowLayout();
            } else {
                return (Border) Class.forName(border).newInstance();
            }
        } catch (Exception e) {
            throw new RuntimeException(e.toString());
        }
    }

    private LayoutManager getLayout(String layout, String init) {
        try {
            if (init != null) {
                Object o = getConstraint(layout, init);
                Class cl;
                if (o instanceof Integer) {
                    cl = int.class;
                } else if (o instanceof Boolean) {
                    cl = boolean.class;
                } else if (o instanceof Double) {
                    cl = double.class;
                } else if (o instanceof Float) {
                    cl = float.class;
                } else if (o instanceof Byte) {
                    cl = byte.class;
                } else if (o instanceof Character) {
                    cl = char.class;
                } else {
                    cl = o.getClass();
                }

                Constructor c = Class.forName(layout).getConstructor(new Class[]{cl});

                return (LayoutManager) c.newInstance(new Object[]{o});

                //return new java.awt.FlowLayout();
            } else {
                return (LayoutManager) Class.forName(layout).newInstance();
            }
        } catch (Exception e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Object getConstraint(String layout, String init) {
        try {
            return Class.forName(layout).getField(init).get(null);
        } catch (Exception e) {
            return init;
        }
    }

    private Color getColor(String value) {
        if (value.indexOf(",") > -1 && value.lastIndexOf(",") != value.indexOf(",")) {
            return new Color(Integer.parseInt(value.substring(0, value.indexOf(","))), Integer.parseInt(value.substring(value.indexOf(",") + 1, value.lastIndexOf(","))), Integer.parseInt(value.substring(value.lastIndexOf(",") + 1)));
        }

        return null;
    }

    private BandListener getBandListener(String c, String init) {
        try {
            if (init != null) {
                Object o = getConstraint(c, init);
                Class cl;
                if (o instanceof Integer) {
                    cl = int.class;
                } else if (o instanceof Boolean) {
                    cl = boolean.class;
                } else if (o instanceof Double) {
                    cl = double.class;
                } else if (o instanceof Float) {
                    cl = float.class;
                } else if (o instanceof Byte) {
                    cl = byte.class;
                } else if (o instanceof Character) {
                    cl = char.class;
                } else {
                    cl = o.getClass();
                }

                Constructor constructor = Class.forName(c).getConstructor(new Class[]{cl});

                return (BandListener) constructor.newInstance(new Object[]{o});
            } else {
                return (BandListener) Class.forName(c).newInstance();
            }
        } catch (Exception e) {
            throw new RuntimeException(e.toString());
        }
    }

    private int getFunctionNumber(String s) {
        if (s.equalsIgnoreCase("now")) {
            return Label.NOW;
        } else if (s.equalsIgnoreCase("date")) {
            return Label.DATE;
        } else if (s.equalsIgnoreCase("time")) {
            return Label.TIME;
        } else if (s.equalsIgnoreCase("page_number")) {
            return Label.PAGE_NUMBER;
        } else if (s.equalsIgnoreCase("number_of_pages")) {
            return Label.NUMBER_OF_PAGES;
        } else if (s.equalsIgnoreCase("database_position")) {
            return Label.DATABASE_POSITION;
        } else {
            return 0;
        }
    }

    private Node findNode(NodeList list, String name) {
        for (int i = 0; i < list.getLength(); i++) {
            if (list.item(i).getNodeName().equals(name)) {
                return list.item(i);
            }
        }

        return null;
    }

    private String checkVariables(String s) {
        if (s != null) {
            if (variables != null && s.indexOf("$") > -1 && s.indexOf("$") != s.lastIndexOf("$")) {
                String temp = s.substring(s.indexOf("$") + 1);

                if (temp.indexOf("$") > -1) {
                    if (variables.containsKey(temp.substring(0, temp.indexOf("$")))) {
                        s = s.substring(0, s.indexOf("$"));
                        s += (variables.get(temp.substring(0, temp.indexOf("$"))) == null ? "" : variables.get(temp.substring(0, temp.indexOf("$"))));
                        s += temp.substring(temp.indexOf("$") + 1);

                        s = checkVariables(s);
                    } else {
                        s = s.substring(0, s.indexOf("$") + 1) + temp.substring(0, temp.indexOf("$") + 1) + checkVariables(temp.substring(temp.indexOf("$") + 1));
                    }
                }
            }

            return s;
        } else {
            return null;
        }
    }
}
